package com.naiterui.ehp.bs.consult.interceptor;

import com.naiterui.ehp.bp.support.context.ResourceHolder;
import com.naiterui.ehp.bp.support.exception.BusinessException;
import com.naiterui.ehp.bp.support.exception.PublicService;
import com.naiterui.ehp.bp.support.security.HeaderConstant;
import com.naiterui.ehp.bp.support.security.SettingConfig;
import com.naiterui.ehp.bp.support.security.VcLoginInterceptor;
import com.naiterui.ehp.bp.support.utils.JsonMapper;
import com.naiterui.ehp.bp.utils.context.SpringContextHolder;
import com.naiterui.ehp.bs.consult.exception.ExceptionCodes;
import com.naiterui.ehp.bs.consult.remote.IVideoConsultRemoter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 用户登录校验器
 *
 * @author mudou
 * @since 2.8.0
 */
@Slf4j
public class LoginInterceptor extends VcLoginInterceptor {

    @Override
    protected boolean verifyToken(HttpServletRequest request, HttpServletResponse response) throws Exception {

        boolean result = false;

        String origin = request.getHeader(HeaderConstant.HEADER_ORIGIN);
        // 如果是医生pc端和小程序端的token 是通过header头传递的
        String tokenHeader = request.getHeader(SettingConfig.TOKEN_HEADER);

        String doctorId = request.getParameter(SettingConfig.DOCTOR_ID);
        String patientId = request.getParameter(SettingConfig.PATIENT_ID);
        String token = request.getParameter(SettingConfig.TOKEN);

        log.info("token:{}", token);
        log.info("tokenHeader:{}", tokenHeader);
        if (StringUtils.isNumeric(origin)) {
            Long id = null;
            switch (Integer.parseInt(origin)) {

                case HeaderConstant.HEADER_ORIGIN_DOCTOR_APP:
                    result = this.checkDrToken(doctorId, token);
                    break;
                case HeaderConstant.HEADER_ORIGIN_PATIENT_WX:
                    result = this.checkPtToken(patientId, token);
                    if (result) {
                        ResourceHolder.bindResource(SettingConfig.PATIENT_ID, Long.valueOf(patientId));
                    }
                    break;
                case HeaderConstant.HEADER_ORIGIN_PATIENT_APP:
                    id = this.checkMiniToken(tokenHeader);
                    if (id != null) {
                        log.info("资源持有器线程上下文-存入数据-VC，patientId {}", id);
                        ResourceHolder.bindResource(SettingConfig.PATIENT_ID, id);
                        result = true;
                    }
                    break;
                case HeaderConstant.HEADER_ORIGIN_DOCTOR_PC:
                    id = checkDoctorPcToken(tokenHeader);
                    if (id != null) {
                        ResourceHolder.bindResource(SettingConfig.DOCTOR_ID, id);
                        result = true;
                    }
                    break;
                default:
                    result = false;
                    break;
            }
        }

        if (!result) {
            response.setHeader("Access-Control-Allow-Origin",request.getHeader("origin"));//支持跨域请求
            response.setHeader("Access-Control-Allow-Methods", "*");
            response.setHeader("Access-Control-Allow-Credentials", "true");//是否支持cookie跨域
            response.setHeader("Access-Control-Allow-Headers", "*");//Origin, X-Requested-With, Content-Type, Accept,Access-Token
            response.setHeader("Access-Control-Max-Age", "3600");
            response.getWriter().println(JsonMapper.toJson(PublicService.returnResponseVO(ExceptionCodes.TOLOGIN)));
        }

        return result;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        super.afterCompletion(request, response, handler, ex);
        // 清空线程变量
        ResourceHolder.clear();
    }

    private boolean checkPtToken(String patientId, String token) {

        return StringUtils.isNoneEmpty(patientId, token);
    }

    private boolean checkDrToken(String doctorId, String token) throws BusinessException {

        if (!StringUtils.isNumeric(doctorId) || StringUtils.isBlank(token)) {
            return false;
        }
        IVideoConsultRemoter remoter = SpringContextHolder.getBean(IVideoConsultRemoter.class);
        return remoter.checkDrToken(doctorId, token);
    }

    private Long checkMiniToken(String token) {
        if (StringUtils.isBlank(token)) {
            return null;
        }
        IVideoConsultRemoter remoter = SpringContextHolder.getBean(IVideoConsultRemoter.class);
        try {
            Long id = remoter.checkMiniToken(token);
            log.info("checkMiniToken id:{}", id);
            return id;
        } catch (BusinessException e) {
            log.error("校验小程序token失败", e);
        }
        return null;
    }

    private Long checkDoctorPcToken(String token){
        if (StringUtils.isBlank(token)) {
            return null;
        }
        IVideoConsultRemoter remoter = SpringContextHolder.getBean(IVideoConsultRemoter.class);
        try {
            Long id = remoter.checkDoctorPcToken(token);
            log.info("checkDoctorPcToken id:{}", id);
            return id;
        } catch (BusinessException e) {
            log.error("校验医生pc端token失败", e);
        }
        return null;
    }
}
